package main;

import java.io.*;

public class Input extends Main{
	
	static BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
	
	
	public static void takeInput() throws NumberFormatException, IOException{
		
		System.out.println("Please Enter the Memory Capacity (in bytes)");        
        capacity = Integer.parseInt(stdin.readLine());

        System.out.println("Please Enter the Number of Cycles to access Memory");        
        n_data_mem = Integer.parseInt(stdin.readLine());

	    System.out.println("Please Enter the Number of Cache Levels");
	    n_cache_levels = Integer.parseInt(stdin.readLine());
	    
	    System.out.println("Please Enter the Number of Data Memory Values to begin Initially \n Note: Address R0 is always 0");
	    int dm_num = Integer.parseInt(stdin.readLine());
	    
	    for(int i = 0; i < dm_num; i++) {
	    
	    System.out.println("Please Enter the Address of The Data in bytes");
	    int data_add = Integer.parseInt(stdin.readLine());
	    
   	    System.out.println("Please Enter the Value of The Data");
	    int data_val = Integer.parseInt(stdin.readLine());
	    
	    DataMemory.put(data_add/2,data_val);
	    	    
	    }
	    
	    for(int i = 0; i < n_cache_levels; i++) {
	    
	    System.out.println("Please Enter number of cycles for level " + (i + 1));
		cache_cycles[i] = Integer.parseInt(stdin.readLine());
	    	
	    System.out.println("Please Enter the S value of level " + (i + 1));
	    S[i] = Integer.parseInt(stdin.readLine());
	    
   	    System.out.println("Please Enter the l value of level " + (i + 1));
	    l[i] = Integer.parseInt(stdin.readLine());
	    
   	    System.out.println("Please Enter the m value of level " + (i + 1));
	    m[i] = Integer.parseInt(stdin.readLine());
	    
	    C[i] = S[i]/l[i];
	    
   	    System.out.println("Please Enter the Writing Policy for hit of level " + (i + 1) + " 0 = write through, 1 = write back");
	    writingPolicy_hit[i] = (Integer.parseInt(stdin.readLine()) == 1);	        

   	    System.out.println("Please Enter the Writing Policy for miss of level " + (i + 1) + " 0 = write allocate, 1 = write around");
	    writingPolicy_miss[i] = (Integer.parseInt(stdin.readLine()) == 0);	
	    	    
	    }
	    
	    CacheEntry.initializeCaches();
	    	    
	    System.out.println("Please Enter The Number of Instructions  per Dispatch (ways):");
		ways = Integer.parseInt(stdin.readLine());
	    
		
		System.out.println("Please Enter Instruciton Buffer size");
		ib_size = Integer.parseInt(stdin.readLine());//10
		
		System.out.println("Please Enter ROB size");
		ROBSize = Integer.parseInt(stdin.readLine());//10
		
		System.out.println("Please Enter Number of Reservation Stations");
		res_stat_num = Integer.parseInt(stdin.readLine());//4
		
		IBIndex = 0;
		
		for(int i=0; i<RegFile.length; i++) RegFile[i] = 0;
	
		System.out.println("Please Enter the Number of ADD/SUB functional Units");
		num_add = Integer.parseInt(stdin.readLine());

		System.out.println("Please Enter its Number of Cycles:");
		cycles_add = Integer.parseInt(stdin.readLine());

		for(int j=0; j<num_add; j++)
		FS.add(new FunctionalUnit('a', cycles_add));
		
		System.out.println("Please Enter the Number of MUL functional Units");
		num_mul = Integer.parseInt(stdin.readLine());

		System.out.println("Please Enter its Number of Cycles:");
		cycles_mul = Integer.parseInt(stdin.readLine());

		for(int j=0; j<num_mul; j++)
		FS.add(new FunctionalUnit('m', cycles_mul));
		
		System.out.println("Please Enter the Number of DIV functional Units");
		num_div = Integer.parseInt(stdin.readLine());

		System.out.println("Please Enter its Number of Cycles:");
		cycles_div = Integer.parseInt(stdin.readLine());

		for(int j=0; j<num_div; j++)
		FS.add(new FunctionalUnit('d', cycles_div));
		
		System.out.println("Please Enter the Number of NAND functional Units");
		num_nand = Integer.parseInt(stdin.readLine());

		System.out.println("Please Enter its Number of Cycles:");
		cycles_nand = Integer.parseInt(stdin.readLine());

		for(int j=0; j<num_nand; j++)
		FS.add(new FunctionalUnit('n', cycles_nand));
	}
	
	public static void AssemblyFile() throws NumberFormatException, IOException {
		
		System.out.println("Please Enter The Program Start Address (in bytes):");
		int startAddress = Integer.parseInt(stdin.readLine())/2;
		
		System.out.println("Please Enter The Number of Instructions to Process:");
		int num = Integer.parseInt(stdin.readLine());
		PC = startAddress;
		END = startAddress+num;
		
		for(int i = 0; i < num; i ++){
			
			 System.out.println("Enter the type of Instruction " + (i + 1));
			 String type = instructionType();
			 System.out.println(type+" Instruction");
			 
			 int dest;
			 if(type.equals("LW") || Instruction.isArithmetic(type)
				|| (type.equals("JALR"))){
			 
			 System.out.println("Enter the destination register");
			 dest = Integer.parseInt(stdin.readLine());
			 
			 }
			 
			 else dest = -1;
			 
			 int source1;
			 System.out.println("Enter Source 1 Register");
			 source1 = Integer.parseInt(stdin.readLine());
			 
			 int source2;
			 if(type.equals("SW") 
				|| (Instruction.isArithmetic(type) && !type.equals("ADDI"))
				|| (type.equals("BEQ"))){
			 				 
			 System.out.println("Enter Source 2 Register");
			 source2 = Integer.parseInt(stdin.readLine());
			 }
			 
			 else source2 = 0;
			 
			 int immed;
			 if(Instruction.isMemory(type) || type.equals("ADDI")
				|| type.equals("BEQ") || type.equals("JMP")){
			 
			 System.out.println("Enter Immediate Value ranging from [-64,63]");
			 immed = Integer.parseInt(stdin.readLine());
			 }
			 
			 else immed = 0;
			 
			IMemory.put(startAddress+i, 
			new Instruction(type, dest, source1, source2, immed, 0, "").reformat());
			 
			 
		}
		
	}
	
	public static String instructionType() throws NumberFormatException, IOException {
		
		System.out.println("0 (ADD)");
		System.out.println("1 (ADDI)");
		System.out.println("2 (MUL)");
		System.out.println("3 (DIV)");
		System.out.println("4 (NAND)");
		System.out.println("5 (LW)");
		System.out.println("6 (SW)");
		System.out.println("7 (JALR)");
		System.out.println("8 (BEQ)");
		System.out.println("9 (JMP)");
		System.out.println("10 (RET)");
		
		switch(Integer.parseInt(stdin.readLine())) {
			
		case 0 : return "ADD";
		case 1 : return "ADDI";
		case 2 : return "MUL";
		case 3 : return "DIV";
		case 4 : return "NAND";
		case 5 : return "LW";
		case 6 : return "SW";
		case 7 : return "JALR";
		case 8 : return "BEQ";
		case 9 : return "JMP";
		case 10 : return "RET";
			
		}
		
		return "ADD";
	}

}
